﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;

namespace Flight
{
    public abstract class Aircraft
    {
        public readonly Model MODEL;
        public float VIEW_DISTANCE; // pixels
        public float VIEW_Z; // pixels

        protected ControlInputs lastControlInputs;

        protected IAutopilot autopilot;

        protected Vector3 loc; // pixels
        protected float heading, pitch; // degrees

        protected Vector3 lastVel; // pixels/second
        protected float lastVSpeed; // pixels/second

        public Aircraft(Model model, float viewDistance, float viewZ, IAutopilot autopilot, 
            Vector3 loc, float heading, float pitch)
        {
            this.MODEL = model;
            this.VIEW_DISTANCE = viewDistance;
            this.VIEW_Z = viewZ;
            this.lastControlInputs = new ControlInputs(0f, 0f, 0f, true);
            this.autopilot = autopilot;
            this.loc = loc;
            this.heading = heading;
            this.pitch = pitch;
            this.lastVel = Vector3.Zero;
            this.lastVSpeed = 0;
        }

        public void update(float frameTime)
        {
            update(frameTime, lastControlInputs);
        }
        public void update(float frameTime, ControlInputs inputs)
        {
            Vector3 prevLoc = loc;

            lastControlInputs = inputs;
            if (autopilot != null)
            {
                autopilot.update(frameTime, this, inputs);
                inputs = autopilot.getControlInputs(this, inputs);
            }
            this.no_autopilot_update(frameTime, inputs);

            // vel = cur - prev
            this.lastVel = (loc - prevLoc) / frameTime;
            this.lastVSpeed = this.lastVel.Z;
        }

        protected abstract void no_autopilot_update(float frameTime, ControlInputs inputs);

        public abstract void draw();

        public IAutopilot getAutopilot() { return autopilot; }
        public Vector3 getLoc() { return loc; }
        public float getHeading() { return heading; }
        public float getPitch() { return pitch; }
        public Vector3 getLastVel() { return lastVel; }
        public float getVSpeed() { return lastVSpeed; }
        public bool isOnGround() { return loc.Z <= 0; }

        public static Aircraft load(String name, Vector3 loc, float heading, float vel)
        {
            Settings settings = new Settings("aircrafts/" + name + "/settings.txt");
            string type = settings.get<string>("type");

            if (type == "airplane")
                return new Airplane(loc, name, heading, vel);
            else if (type == "helicopter")
                return new Helicopter(loc, name, heading, vel);
            else throw new Exception("Forgot an aircraft type in Aircraft.load(...).");
        }
        public static Aircraft load(String name, Model model, Vector3 loc, float heading, float vel)
        {
            Settings settings = new Settings("aircrafts/" + name + "/settings.txt");
            string type = settings.get<string>("type");

            if (type == "airplane")
                return new Airplane(loc, name, heading, vel, model);
            else if (type == "helicopter")
                return new Helicopter(loc, name, heading, vel, model);
            else throw new Exception("Forgot an aircraft type in Aircraft.load(...).");
        }
    }
}
